<template>
  <div class="preview-image">
    <!-- 渲染图片 -->
    <template v-if="Array.isArray(urls)">
      <div
          v-for="(url, index) in urls"
          :key="index"
          class="image-container"
          :style="{ width: containerSize.width, height: containerSize.height }"
          @mouseenter="handleMouseEnter(index)"
          @mouseleave="handleMouseLeave()"
      >
        <el-image class="image" fit="cover" :src="url" />
        <div
            v-if="hoveredIndex === index"
            class="close-button"
            @click="removeImage(index)"
        >
          <el-icon :size="16">
            <Close />
          </el-icon>
        </div>
      </div>
    </template>
    <template v-else-if="urls">
      <div
          class="image-container"
          :style="{ width: containerSize.width, height: containerSize.height }"
          @mouseenter="handleMouseEnter(0)"
          @mouseleave="handleMouseLeave()"
      >
        <el-image class="image" fit="cover" :src="urls" />
        <div
            v-if="hoveredIndex === 0"
            class="close-button"
            @click="removeImage()"
        >
          <el-icon :size="16">
            <Close />
          </el-icon>
        </div>
      </div>
    </template>

    <!-- 根据条件渲染上传按钮 -->
    <div
        v-if="shouldShowUpload"
        class="upload"
        :style="{ width: containerSize.width, height: containerSize.height }"
        @click="handleClick"
    >
      <el-icon :size="22" class="icon">
        <Plus />
      </el-icon>
      <span class="text" v-if="props.text !== ''">{{ props.text }}</span>
    </div>
  </div>
  <!-- 文件管理 -->
  <el-dialog v-model="dialogVisible" title="上传图片" width="1200">
    <UploadFiles dialog :multiple="props.multiple" @useImage="handleUseImage" />
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";
import UploadFiles from "@/components/UploadFiles.vue";
import { Plus, Close } from "@element-plus/icons-vue";

// 定义组件属性
const props = withDefaults(defineProps<{
  multiple: boolean;
  modelValue: string | string[];
  text?: string;
  width?: string; // 新增：自定义宽度
  height?: string; // 新增：自定义高度
}>(), {
  multiple: false,
  modelValue: (props) => (props.multiple ? [] : ""),
  text: "",
  width: "100px", // 默认宽度
  height: "100px", // 默认高度
});

// 定义 emit
const emit = defineEmits(["update:modelValue"]);

const dialogVisible = ref(false);
const urls = ref<string | string[]>([]);
const hoveredIndex = ref<number | null>(null);

// 监听父组件传递的 modelValue，更新子组件的 urls
watch(
    () => props.modelValue,
    (newValue) => {
      urls.value = newValue || (props.multiple ? [] : "");
    },
    { immediate: true }
);

// 动态计算容器宽高
const containerSize = computed(() => ({
  width: props.width,
  height: props.height,
}));

// 计算属性：决定是否应该显示上传按钮
const shouldShowUpload = computed(() => {
  if (props.multiple) return true;
  return !urls.value || (!Array.isArray(urls.value) && !urls.value);
});

const handleClick = () => {
  dialogVisible.value = true;
};

// 选中图片
const handleUseImage = (url: string | string[]) => {
  if (props.multiple) {
    if (Array.isArray(url)) {
      urls.value = url; // 多图模式，直接赋值
    }
  } else {
    if (typeof url === "string" || Array.isArray(url)) {
      urls.value = Array.isArray(url) ? url[0] || "" : url; // 单图模式，只取第一张
    }
  }
  emit("update:modelValue", urls.value); // 通知父组件
  dialogVisible.value = false;
};

// 移除图片
const removeImage = (index?: number) => {
  if (props.multiple && Array.isArray(urls.value)) {
    urls.value.splice(index, 1); // 多图模式，移除指定图片
  } else {
    urls.value = ""; // 单图模式，清空图片
  }
  emit("update:modelValue", urls.value); // 通知父组件
};

// 鼠标停留在图片上
const handleMouseEnter = (index: number) => {
  hoveredIndex.value = index;
};

// 鼠标移除出图片
const handleMouseLeave = () => {
  hoveredIndex.value = null;
};
</script>

<style scoped lang="scss">
.preview-image {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 10px;
}

.image-container {
  position: relative;
}

.image {
  width: 100%;
  height: 100%;
}

.close-button {
  position: absolute;
  top: -10px;
  right: -10px;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  padding: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;

  .el-icon {
    color: white;
  }

  &:hover {
    background-color: rgba(255, 0, 0, 0.7);
  }
}

.upload {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 100px;
  border: 1px dashed var(--el-border-color);
  border-radius: 4px;
  cursor: pointer;

  &:hover {
    border: 1px dashed var(--el-color-primary);

    .icon {
      color: var(--el-color-primary);
    }

    .text {
      color: var(--el-color-primary);
    }
  }

  .icon {
    font-weight: 700;
    color: var(--el-text-color-regular);
  }

  .text {
    font-weight: 700;
    color: var(--el-text-color-regular);
    margin-top: 10px;
  }
}
</style>